/*
 * FileInfo.h
 *
 *  Created on: 24.06.2011
 *      Author: mario
 */

#ifndef FILEINFO_H_
#define FILEINFO_H_

// system
#include <string>
#include <queue>
#include <time.h>
#include <boost/shared_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>
#include <fstream>
#include <iostream>
#include <boost/thread.hpp>

// omnibus
#include "User.h"
#include "Userdatabase.h"

// interfaces
#include "interfaces/TransferBundleInterface.h"



#define for_each BOOST_FOREACH

using namespace std;
using boost::shared_ptr;
using boost::property_tree::ptree;


class FileInfo
{
public:
  FileInfo();
  FileInfo(string key, string filename, uint64_t size, UserPtr partner);
  FileInfo(ptree &pt, Userdatabase* users);
  virtual ~FileInfo();

  string get_key();
  string get_filename();
  uint64_t get_size();
  bool get_acceptance();
  string get_path();
  UserPtr get_partner();
  uint64_t get_transferred();

  void set_acceptance(bool b);
  void set_path(string p);
  void set_size(uint64_t size);
  void set_transferred(uint64_t pos);
  void set_pause(bool pause, bool just_hold);
  void inc_transferred(uint64_t n);
  
  // flow control
  void inc_unacked_pkg();
  void dec_unacked_pkg();
  int get_unacked_pkg() const;
  
  bool is_complete();
  bool is_paused();
  bool get_try_resume();
  void set_finished();
  void status(ptree &pt);
  
  bool is_active();

  void save(ptree &pt);

  /* file operations */
  int append(char* buff, int len);
  void file_close();

  bool operator!(void);
    void set_filename(string filename);
    void set_key(string key);
    void set_partner(UserPtr partner);
    TransferBundlePtr get_bundle() const;
    void set_bundle(TransferBundlePtr bundle);
    

private:
    // measure time consumed in active state
    time_t get_transfer_time();
    void trigger_timing();

private:
    string key;
    string filename;    // XXX Filename ist sozusagen der angezeigte Name. Im Normalfall wird auch der Dateiname daraus erstellt.
    uint64_t size;
    uint64_t transferred;

    UserPtr partner;
    string path;        // XXX Path ist der komplette Dateiname (ggf. relativ) incl. Dateinamen
    bool transfer_accepted;
    bool transfer_paused;
    bool try_resume_paused_transfer;
    
    // timing
    time_t time_consumed;
    time_t unpaused_at;
    
    // flow control
    int unacked_pkg;

    ofstream file;

    bool finished;

    TransferBundlePtr bundle;
};

typedef boost::shared_ptr<FileInfo> FilePtr;

#endif /* FILEINFO_H_ */
